<template>
  <el-form
      :model="queryForm"
      ref="queryFormRef"
      :inline="true"
      label-width="70px"
  >
    <el-form-item label="角色名称" prop="roleName">
      <el-input
          v-model="queryForm.roleName"
          placeholder="请输入角色名称"
          clearable
          style="width: 240px"
          @keyup.enter.native="handleQuery()"
      />
    </el-form-item>
    <el-form-item label="权限字符" prop="roleKey">
      <el-input
          v-model="queryForm.roleKey"
          placeholder="请输入权限字符"
          clearable
          style="width: 240px"
          @keyup.enter.native="handleQuery()"
          @change="handleQuery()"
      />
    </el-form-item>
    <el-form-item label="状态" prop="status">
      <el-select
          v-model="queryForm.status"
          placeholder="角色状态"
          clearable
          @change="handleQuery()"
          style="width: 240px"
      >
        <el-option
            v-for="dict in statusOptions"
            :key="dict.label"
            :label="dict.label"
            :value="dict.value"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="创建时间" style="font-weight: bold">
      <el-date-picker
          v-model="dateRange"
          style="width: 240px"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          clearable
          @change="handleQuery()"
      ></el-date-picker>
    </el-form-item>
    <el-form-item class="item-search">
      <el-button @click="resetClick">重置</el-button>
      <el-button type="primary" @click="handleQuery">搜索</el-button>
      <el-button
          type="primary"
          plain
          @click="handleAdd"
      >新增</el-button
      >
    </el-form-item>
  </el-form>
  <Tbale
      :isSelect="true"
      :table-data="tableData"
      :table-column="tableColumn"
      @pagination-change="getList"
      v-model:page-num="queryForm.pageNum"
      v-model:page-size="queryForm.pageSize"
      :total="total">
    <template #edit="{row}">
      <el-link
          v-if="row.roleId !== '1'"
          class="el-link-spacing"
          :underline="false"
          size="small"
          type="primary"
          icon="edit"
          @click="handleUpdate(row)"
      ><span class="table_link_text">修改</span></el-link>
      <el-link
          v-if="row.roleId !== '1'"
          class="el-link-spacing"
          :underline="false"
          size="small"
          type="primary"
          icon="circle-check"
          @click="handleDataScope(row)"
      ><span class="table_link_text">数据权限</span></el-link>
      <el-link
          v-if="row.roleId !== '1'"
          class="el-link-spacing"
          :underline="false"
          size="small"
          type="danger"
          icon="delete"
          @click="handleDelete(row)"
      ><span class="table_link_text">删除</span></el-link>
    </template>
  </Tbale>

  <!-- 添加或修改角色配置对话框 -->
  <el-dialog
      :title="title"
      v-model="open"
      width="30%"
      append-to-body
  >
    <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="90px"
    >
      <el-row>
        <el-col :span="12">
          <el-form-item label="角色名称" prop="roleName">
            <el-input
                v-model="form.roleName"
                placeholder="请输入角色名称"
                style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="权限字符" prop="roleKey">
            <el-input
                v-model="form.roleKey"
                placeholder="请输入权限字符"
                style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="角色顺序" prop="roleSort">
            <el-input-number
                v-model="form.roleSort"
                controls-position="right"
                :min="0"
                style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="角色状态">
            <el-radio-group v-model="form.status">
              <el-radio
                  v-for="dict in statusOptions"
                  :value="dict.value"
                  :key="dict.value"
                  :label="dict.label"
              >{{ dict.label }}
              </el-radio
              >
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="菜单权限">
            <!-- prettier-ignore -->
            <el-checkbox
                v-model="menuExpand"
                @change="handleCheckedTreeExpand($event, 'menu')"
            >展开/折叠
            </el-checkbox
            >
            <!-- prettier-ignore -->
            <el-checkbox
                v-model="menuNodeAll"
                @change="handleCheckedTreeNodeAll($event, 'menu')"
            >全选/全不选
            </el-checkbox
            >
            <!-- prettier-ignore -->
            <el-checkbox
                v-model="form.menuCheckStrictly"
                @change="handleCheckedTreeConnect($event, 'menu')"
            >父子联动
            </el-checkbox
            >
            <el-tree
                class="tree-border"
                :data="menuOptions"
                show-checkbox
                ref="menuRef"
                node-key="id"
                :check-strictly="!form.menuCheckStrictly"
                empty-text="加载中，请稍后"
                :props="defaultProps"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注">
            <el-input
                v-model="form.remark"
                type="textarea"
                :autosize="{ minRows: 4 }"
                placeholder="请输入内容"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <!-- prettier-ignore -->
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="open = false">取 消</el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 分配角色数据权限对话框 -->
  <el-dialog
      :title="title"
      v-model="openDataScope"
      width="20%"
      append-to-body

  >
    <el-form :model="form" label-width="80px">
      <el-form-item label="角色名称">
        <el-input v-model="form.roleName" :disabled="true"/>
      </el-form-item>
      <el-form-item label="权限字符">
        <el-input v-model="form.roleKey" :disabled="true"/>
      </el-form-item>
      <el-form-item label="权限范围">
        <el-select
            v-model="form.dataScope"
            @change="dataScopeSelectChange"
        >
          <el-option
              v-for="item in dataScopeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="数据权限" v-show="form.dataScope == 2">
        <el-checkbox
            v-model="deptExpand"
            @change="handleCheckedTreeExpand($event, 'dept')"
        >展开/折叠
        </el-checkbox
        >
        <el-checkbox
            v-model="deptNodeAll"
            @change="handleCheckedTreeNodeAll($event, 'dept')"
        >全选/全不选
        </el-checkbox
        >
        <el-checkbox
            v-model="form.deptCheckStrictly"
            @change="handleCheckedTreeConnect($event, 'dept')"
        >父子联动
        </el-checkbox
        >
        <el-tree
            class="tree-border"
            :data="deptOptions"
            show-checkbox
            default-expand-all
            ref="deptRef"
            node-key="id"
            :check-strictly="!form.deptCheckStrictly"
            empty-text="加载中，请稍后"
            :props="defaultProps"
        ></el-tree>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <!-- prettier-ignore -->
        <el-button type="primary" @click="submitDataScope">确 定</el-button>
        <el-button @click="openDataScope = false">取 消</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import Tbale from "@/components/Table/ElTable.vue";
import {getCurrentInstance, nextTick, onMounted, ref} from "vue";
import {roleMenuTreeSelect, treeselect as menuTreeselect} from "@/api/system/menu.ts";
import {addRole, dataScope, delRole, getRole, listRole, updateRole} from "@/api/system/role.ts";
import {addDateRange} from "@/utils/z.ts";
import {ElForm, ElMessage, ElMessageBox, ElTree} from "element-plus";
import {roleDeptTreeselect} from "@/api/system/dept.ts";

const {proxy} = getCurrentInstance();
onMounted(() => {
  getList()
})
const queryForm = ref(
    {
      pageNum: 1,
      pageSize: 10,
      roleName: undefined,
      roleKey: undefined,
      status: undefined,
    }
)
const total = ref(0)


// 弹出层标题
const title = ref<string>("");
// 是否显示弹出层
const open = ref<boolean>(false);
// 是否显示弹出层（数据权限）
const openDataScope = ref<boolean>(false);
const menuExpand = ref<any>();
const menuNodeAll = ref<any>(false);
const deptExpand = ref<any>();
const deptNodeAll = ref<any>(false);
const menuRef = ref<InstanceType<typeof ElTree>>();
const deptRef = ref<InstanceType<typeof ElTree>>();
const formRef = ref<InstanceType<typeof ElForm>>();
const defaultProps = {
  children: "children",
  label: "label",
};
// 状态数据字典
const statusOptions = ref<any>([
  {
    value: "0",
    label: "正常",
  }, {
    value: "1",
    label: "停用",
  },
]);
// 数据范围选项
const dataScopeOptions = [
  {
    value: "1",
    label: "全部数据权限",
  },
  {
    value: "2",
    label: "自定数据权限",
  },
  {
    value: "3",
    label: "本部门数据权限",
  },
  {
    value: "4",
    label: "本部门及以下数据权限",
  },
  {
    value: "5",
    label: "仅本人数据权限",
  },
];
// 菜单列表
const menuOptions = ref<any>();
// 部门列表
const deptOptions = ref<any>();
// 表单参数
const form = ref<any>({});
// 表单校验
const rules = {
  roleName: [
    {
      required: true,
      message: "角色名称不能为空",
      trigger: "blur",
    },
  ],
  roleKey: [
    {
      required: true,
      message: "权限字符不能为空",
      trigger: "blur",
    },
  ],
  roleSort: [
    {
      required: true,
      message: "角色顺序不能为空",
      trigger: "blur",
    },
  ],
};
// 选中数组
const ids = ref<any>();
const resetClick = () => {
  getList()
}
const getList = () => {
  listRole(addDateRange(queryForm.value, dateRange.value)).then(
      (response: any) => {
        tableData.value = response.rows;
        total.value = parseInt(response.total);
      }
  );
}
const tableData = ref<Array<Object>>([])

const tableColumn = ref<Array<Object>>([
  {
    label: '角色编号',
    prop: 'roleId',

  },
  {
    label: '角色名称',
    prop: 'roleName',

  },
  {
    label: '权限字符',
    prop: 'roleKey',

  }, {
    label: '显示顺序',
    prop: 'roleSort',
  }, {
    label: '备注信息',
    prop: 'remark',
  }, {
    label: '状态',
    prop: 'status',
  }, {
    label: '创建时间',
    prop: 'createTime',
  }, {
    label: '修改时间',
    prop: 'updateTime',
  }, {
    label: '操作',
    prop: 'edit',
    slot: true,
  },
])


const handleQuery = () => {
  getList()
}

// 日期范围
const dateRange = ref<any>();

// 表单重置
const reset = () => {
  if (menuRef.value != undefined) {
    menuRef.value.setCheckedKeys([]);
  }
  menuExpand.value = false;
  menuNodeAll.value = false;
  deptExpand.value = true;
  deptNodeAll.value = false;
  form.value = {
    roleId: undefined,
    roleName: undefined,
    roleKey: undefined,
    roleSort: 0,
    status: "0",
    menuIds: [],
    deptIds: [],
    menuCheckStrictly: true,
    deptCheckStrictly: true,
    remark: undefined,
  };

};

/** 修改按钮操作 */
const handleUpdate = (row: any) => {

  reset();
  const roleId = row.roleId || ids.value[0];
  if (!roleId) {
    return;
  }
  getRole(roleId).then((response: any) => {
    if (response.code === 200) {
      // 转换下避免出现警告
      response.data.roleSort = parseInt(response.data.roleSort);
      form.value = response.data;
      open.value = true;
      nextTick(() => {
        roleMenuTreeSelect(roleId).then((res: { code: number; data: { checkedKeys: any } }) => {
              if (res.code === 200) {
                menuOptions.value = res.menus;
                const checkedKeys = res.checkedKeys;
                checkedKeys.forEach((v: any) => {
                  nextTick(() => {
                    // prettier-ignore
                    menuRef.value?.setChecked(v, true, false);
                  });
                });
              }
            }
        );
      });
      title.value = "修改角色";
    }
  });
};
/** 选择角色权限范围触发 */
const dataScopeSelectChange = (value: string) => {
  if (value !== "2") {
    deptRef.value?.setCheckedKeys([]);
  }
};
// 树权限（展开/折叠）
const handleCheckedTreeExpand = (value: any, type: string) => {
  if (type === "menu") {
    let treeList = menuOptions.value;
    for (let i = 0; i < treeList.length; i++) {
      // prettier-ignore
      proxy.$refs.menuRef.store.nodesMap[treeList[i].id].expanded = value;
    }
  } else if (type === "dept") {
    let treeList = deptOptions.value;
    for (let i = 0; i < treeList.length; i++) {
      // prettier-ignore
      proxy.$refs.deptRef.store.nodesMap[treeList[i].id].expanded = value;
    }
  }
};
// 树权限（全选/全不选）
const handleCheckedTreeNodeAll = (value: any, type: string) => {
  if (type === "menu") {
    menuRef.value?.setCheckedNodes(value ? menuOptions.value : []);
  } else if (type === "dept") {
    deptRef.value?.setCheckedNodes(value ? deptOptions.value : []);
  }
};
// 树权限（父子联动）
const handleCheckedTreeConnect = (value: any, type: string) => {
  if (type == "menu") {
    form.value.menuCheckStrictly = value ? true : false;
  } else if (type == "dept") {
    form.value.deptCheckStrictly = value ? true : false;
  }
};
/** 提交按钮（数据权限） */
const submitDataScope = () => {
  if (form.value.roleId !== undefined) {
    form.value.deptIds = getDeptAllCheckedKeys();
    dataScope(form.value).then((response: any) => {
      if (response.code === 200) {
        ElMessage({message: "修改成功", type: 'success'})
        openDataScope.value = false;
        getList();
      }
    });
  }
};

// 所有部门节点数据
const getDeptAllCheckedKeys = () => {
  // 目前被选中的部门节点
  let checkedKeys = deptRef.value?.getCheckedKeys() as any;
  // 半选中的部门节点
  let halfCheckedKeys = deptRef.value?.getHalfCheckedKeys();
  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
  return checkedKeys;
};
/** 提交按钮 */
const submitForm = () => {
  formRef.value?.validate((valid: boolean) => {
    if (valid) {
      if (form.value.roleId !== undefined) {
        form.value.menuIds = getMenuAllCheckedKeys();
        updateRole(form.value).then((response: any) => {
          if (response.code === 200) {
            ElMessage({message: "修改成功", type: 'success'})
            open.value = false;
            getList();
          }
        });
      } else {
        form.value.menuIds = getMenuAllCheckedKeys();
        addRole(form.value).then((response: any) => {
          if (response.code === 200) {
            ElMessage({message: "新增成功", type: 'success'})
            open.value = false;
            getList();
          }
        });
      }
    }
  });
};
// 所有菜单节点数据
const getMenuAllCheckedKeys = () => {
  // 目前被选中的菜单节点
  let checkedKeys = menuRef.value?.getCheckedKeys() as any;
  // 半选中的菜单节点
  let halfCheckedKeys = menuRef.value?.getHalfCheckedKeys();
  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
  return checkedKeys;
};
/** 根据角色ID查询部门树结构 */
const getRoleDeptTreeselect = (roleId: string) => {
  return roleDeptTreeselect(roleId).then((response: any) => {
    if (response.code === 200) {
      deptOptions.value = response.data.depts;
      return response;
    }
  });
};
/** 分配数据权限操作 */
const handleDataScope = (row: any) => {
  reset();
  getRole(row.roleId).then((response: any) => {
    if (response.code === 200) {
      openDataScope.value = true;
      // 转换下避免出现警告
      response.data.roleSort = parseInt(response.data.roleSort);
      form.value = response.data;
      setTimeout(() => {
        nextTick(() => {
          roleDeptTreeselect(row.roleId).then(
              (res: { data: { checkedKeys: any } }) => {
                deptOptions.value = res.depts;
                // prettier-ignore
                deptRef.value?.setCheckedKeys(res.data.checkedKeys);
              }
          );
        });
      }, 100);
      title.value = "分配数据权限";
    }
  });
};
/** 删除按钮操作 */
const handleDelete = (row: any) => {
  console.log(!row || !ids.value,'row')
  console.log(!row,'row1')
  if (!row &&!ids.value) {
    return;
  }
  console.log(row,'row1')
  const roleIds = row.roleId || ids.value;
  if (!roleIds) {
    return;
  }
  // prettier-ignore
  ElMessageBox.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?',)
      .then(() => {
        return delRole(roleIds);
      })
      .then((response: { code: number; }) => {
        if (response.code === 200) {
          getList();
          ElMessage({message: "删除成功", type: 'warning'})
        }
      }).catch(() => {

    console.log("删除操作取消");
  });
};
/** 新增按钮操作 */
const handleAdd = () => {
  reset();
  getMenuTreeselect();
  open.value = true;
  title.value = "添加角色";
};
/** 查询菜单树结构 */
const getMenuTreeselect = () => {
  menuTreeselect().then((response: any) => {
    if (response.code === 200) {
      menuOptions.value = response.data;
    }
  });
};
</script>
<style scoped>

</style>
